home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / SDKs / ScreenLight™ 1.0.1 / CodeExamples / ModuleRoutines.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-05  |  10.7 KB  |  373 lines  |  [TEXT/CWIE]

  1. /**********************************************************************************
  2.   ModuleRoutines.c
  3.  
  4.  
  5.         DOCUMENTATION
  6.  
  7.                 Module support routines for Meddle, the Fat Binary
  8.  
  9.  
  10.         ROUTINE DESCRIPTIONS
  11.  
  12.                 InitmProcs()
  13.                 CheckRequiredFeatures()
  14.                 hasPowerPCArch()
  15.                 ProfileMonitors()
  16.                 GetLargestRect()
  17.                 IsColorPort()
  18.                 GetPortPixDepth()
  19.                 CalcHSBtoRGB()
  20.                 IRandom()
  21.  
  22.  
  23.         HISTORY
  24.  
  25.                 27nov95 bh          New Today
  26.  
  27.  
  28.         Copyright )WORK-IN_PROGRESS  Noesis Software Construction
  29. **********************************************************************************/
  30.  
  31. #include "ModuleRoutines.h"
  32.  
  33.  
  34. //--------------------------------------------------
  35. OSErr InitmProcs( ModuleParamBlkPtr mpPtr)
  36. {
  37.     extern OSErr ModDraw( ModuleParamBlkPtr mpPtr);
  38.     extern OSErr ModClose( ModuleParamBlkPtr mpPtr);
  39.     extern OSErr ModChangePrefs( ModuleParamBlkPtr mpPtr);
  40.     
  41.     // allocate proc pointers
  42.     mpPtr->mProcs.drawProc = NewModDrawProc(ModDraw);
  43.     mpPtr->mProcs.closeProc = NewModCloseProc(ModClose);
  44.     mpPtr->mProcs.chngPrefsProc = NewModChangePrefsProc(ModChangePrefs);
  45.     mpPtr->mProcs.aboutProc = 0;
  46.  
  47.     return noErr;
  48. }
  49.  
  50.  
  51. //-----------------------------------------------------------------------
  52. // CheckRequiredFeatures
  53. //
  54. //         You may want to copy this routine into your own Module code
  55. //        and modify the requirements to check for features
  56. //          needed by your module.
  57. //
  58. //        When requiring an FPU for your module (generating '881->ON)
  59. //    please remember to add a resource of type 'kFPU' in your module.
  60. //    Your module will then be filtered out on machines without an 
  61. //    FPU, so the check for an FPU is optional here...
  62. //
  63. //        PowerPC's have FPU instructions built in.
  64. //
  65.  
  66. OSErr CheckRequiredFeatures()
  67. {
  68.     SysEnvRec    tEnv;
  69.     OSErr        err;
  70.  
  71.     if ((err=SysEnvirons( 2, &tEnv)) != noErr)
  72.         return (-1);
  73.     
  74.         // Note that there is a bug in Gestalt selector 'qdrw' which
  75.         // tells us incorrectly that CQD is present on non-color 
  76.         // machines. HOWEVER, we use SysEnvirons() to tell us if 
  77.         // CQD is present, and the always correct Gestalt selector
  78.         // 'qd  ' for _version_ information, if we have Gestalt...
  79.  
  80.     if ( !tEnv.hasColorQD)
  81.         return kNoCQDerr;
  82.     
  83.     return noErr;
  84. }
  85.  
  86. //*********************************************************************************
  87. //    hasPowerPCArch 
  88. //
  89. //    Gestalt will return an error if the gestaltSysArchitecture selector is
  90. //    not recognized by the System, so we can assume this is a 68K machine.
  91. //    Otherwise, this function returns true for a Power Mac and false for
  92. //    a 68K Mac.
  93. //
  94. //*********************************************************************************
  95.  
  96. Boolean    hasPowerPCArch()
  97. {
  98.     long    gestaltResult;
  99.  
  100.     if (Gestalt(gestaltSysArchitecture, &gestaltResult))
  101.         return(false);
  102.     else
  103.         return(gestaltResult == gestaltPowerPC);
  104. }
  105.  
  106. //*********************************************************************************
  107. //    IsColorPort    
  108. //                    Simple test for a CGrafPort
  109. //*********************************************************************************
  110. Boolean IsColorPort( GrafPtr tPort)
  111. {
  112.     return (tPort->portBits.rowBytes & 0xC000) != 0;
  113. }
  114.  
  115. //*********************************************************************************
  116. //    GetPortPixDepth    
  117. //                    Return bit-depth of a GrafPort
  118. //*********************************************************************************
  119. short GetPortPixDepth( GrafPtr tPort)
  120. {
  121.     if ( (tPort->portBits.rowBytes & 0xC000) == 0)
  122.         return 1;
  123.     else
  124.         return (*((CGrafPtr)tPort)->portPixMap)->pixelSize;
  125. }
  126.  
  127.  
  128. //*********************************************************************************
  129. // Example Profile Routine
  130. //
  131. //        Modules may wish to profile monitors.  Currently, the Drawing Window
  132. //    is opened across all active Screens using GrayRgn.  In a multiple monitor
  133. //    environment, drawing across all screens may or may not be what the Module
  134. //    wants to do!  SO here is an example routine making a convenient structure
  135. //    containing a few imortant pieces of info on available monitors....
  136. //
  137.  
  138. //include <Quickdraw.h>
  139.  
  140. //------------------------------------------
  141. struct SMonProfile {
  142.     Rect    sMonRect;                // in GLOBAL co-ords
  143.     short    sMonCurDepth;            // always a power of two
  144.     short    sMonType;                // 0=clut,1=fixed,2=direct
  145. };
  146. typedef struct SMonProfile SMonProfile;
  147.  
  148. struct SDeviceList {
  149.     short        sDevCnt;
  150.     SMonProfile    sDevs[1];
  151. };
  152. typedef struct SDeviceList SDeviceList;
  153. //------------------------------------------
  154. OSErr ProfileMonitors(void);
  155.  
  156. //------------------------------------------
  157. OSErr ProfileMonitors(void)
  158. {
  159.     SDeviceList    **xDeviceListH;        // <- make this into a global
  160.     short            cnt;
  161.     GDHandle        device;
  162.     Size            siz;
  163.     OSErr            err = noErr;
  164.     
  165.     cnt = 0;
  166.     xDeviceListH = (SDeviceList    **)NewHandle(0);    // stub
  167.     for (device = GetDeviceList(); device != 0; device = GetNextDevice(device)) {
  168.         if (TestDeviceAttribute(device, screenDevice)
  169.           && TestDeviceAttribute(device, screenActive)) {
  170.               siz = sizeof(SDeviceList) + cnt*sizeof(SMonProfile);
  171.               SetHandleSize( (Handle)xDeviceListH, siz);
  172.               if ( (err=MemError()) != noErr)            // bail if unlikely error occurs
  173.                   return err;
  174.               (**xDeviceListH).sDevs[cnt].sMonRect = (**device).gdRect;
  175.               (**xDeviceListH).sDevs[cnt].sMonCurDepth = (**(**device).gdPMap).pixelSize;
  176.               (**xDeviceListH).sDevs[cnt].sMonType = (**device).gdType;
  177.               cnt++;
  178.         }
  179.     }
  180.     (**xDeviceListH).sDevCnt = cnt;
  181.     return err;
  182. }
  183.  
  184.  
  185. //*********************************************************************************
  186. // GetLargestRect - 
  187. //
  188. //   Here is a sample routine for finding the monitor rect of the largest Monitor
  189. //    for use by a Mosule while drawing in ScreenSaving mode (not inPreview!)
  190. //    Note that the Rect is adjusted by an additional offset at the end of the
  191. //    routine. This is because no matter which monitor your Rect lands on, when 
  192. //    the global drawing window is created, it will be offset by the negative
  193. //    coords of the left and upper-most monitor from the MenuBar. Since the coords
  194. //    of the Drawing window are always 0,0 in the UpperLeft corner, this routine
  195. //  adds an additional offset to compensate.
  196. //
  197.  
  198. void GetLargestRect( Rect *r)
  199. {
  200.     short            cnt;
  201.     long            curWid, curHt, bestWid, bestHt;
  202.     short            mostNegH, mostNegV;
  203.     Rect            bestR, curR;
  204.     GDHandle        device;
  205.     
  206.     *r = qd.screenBits.bounds;
  207.     bestR.left = bestR.right = bestR.top = bestR.bottom = 0;
  208.     bestWid = bestHt = 0;
  209.     mostNegH = mostNegV = 0;
  210.     
  211.     for (device = GetDeviceList(); device != 0; device = GetNextDevice(device)) {
  212.         if (TestDeviceAttribute(device, screenDevice)
  213.           && TestDeviceAttribute(device, screenActive)) {
  214.  
  215.             curR = (**device).gdRect;              
  216.               curWid = (curR.right-curR.left);
  217.               curHt = (curR.bottom-curR.top);
  218.     
  219.               if ( curWid*curHt > bestWid*bestHt) {
  220.                   bestR = curR;
  221.                   bestWid = (bestR.right-bestR.left);
  222.                   bestHt = (bestR.bottom-bestR.top);
  223.               } 
  224.               // Adjust for monitors to the left of the Main Device
  225.               if ( curR.left < mostNegH) mostNegH = curR.left;
  226.               if ( curR.top < mostNegV) mostNegV = curR.top;
  227.         }
  228.     }
  229.  
  230.     *r = bestR;
  231.     r->left -= mostNegH;    r->right -= mostNegH;
  232.     r->top -= mostNegV;        r->bottom -= mostNegV;
  233.  
  234.     return;
  235. }
  236.  
  237.  
  238. //*********************************************************************
  239. // CalcHSBtoRGB
  240. //
  241. //        Use a simple conversion system to get a Mac RGB triplet out
  242. //    of an HSB request.  Hue is measured in 0-360° units, while
  243. //    Saturation and Brightness are in 0-100%.
  244. //
  245. //        Only integer math is used.  There is a rounding error of 
  246. //    1/4 unit per RGB component when calculating the Hue in each
  247. //    sextant - meaning that 59° will result in an RGB triplet that 
  248. //    is 14 units less than it should be in each of RGB. In an 8 bit
  249. //    system this is ignored, but in a 'true color' system this will 
  250. //    cause a slight darkening of the resultant colors. (16/65535 or
  251. //    0.0244 percent error per component)
  252. //
  253. //
  254. //    15aug94 - bh                                        New Today
  255. //--------------------------------------------------------------------
  256.  
  257. OSErr CalcHSBtoRGB( long hue, long sat, long bright, RGBColor *dstRGB)
  258. {
  259.     unsigned short    tComp;
  260.     unsigned short    tProp;
  261.  
  262. #ifdef RANGE_CHK
  263.     if ( hue > 360 || hue < 0) return -1;
  264.     if ( sat > 100 || sat < 0) return -1;
  265.     if ( bright > 100 || bright < 0) return -1;
  266. #endif
  267.  
  268. #if(0)
  269.     if ( hue > 360) hue = hue % 360;
  270.     if ( sat > 100) sat = 100;
  271.     if ( bright > 100) bright = 100;
  272. #endif
  273.     // catch a special case of black
  274.     if ( bright == 0) {
  275.         dstRGB->red   = 0;
  276.         dstRGB->green = 0;
  277.         dstRGB->blue  = 0;
  278.         return noErr;
  279.     }
  280.     
  281.     // catch a special case of white
  282.     if ( sat == 0 ) {
  283.         dstRGB->red = 0xFFFF;
  284.         dstRGB->green = 0xFFFF;
  285.         dstRGB->blue = 0xFFFF;
  286.         return noErr;
  287.     }
  288.     
  289.     //--------------------------------------
  290.     // Set RGB based on hue 
  291.  
  292.     tProp = 0xFFFF/60;
  293.     
  294.     if ( hue <= 60)    {                                    // 0-60  green+
  295.         tComp = hue;
  296.         dstRGB->red = 0xFFFF;
  297.         dstRGB->green = 0 + (tComp * tProp);
  298.         dstRGB->blue = 0;
  299.     } else if ( hue <= 120) {                            // 61-120  red-
  300.         tComp = hue-60;
  301.         dstRGB->red = 0xFFFF - (tComp * tProp);
  302.         dstRGB->green = 0xFFFF;
  303.         dstRGB->blue = 0;
  304.     } else if ( hue <= 180) {                            // 121-180 blue+
  305.         tComp = hue-120;
  306.         dstRGB->red = 0;
  307.         dstRGB->green = 0xFFFF;
  308.         dstRGB->blue = 0 + (tComp * tProp);
  309.     } else if ( hue <= 240) {                            // 181-240 green-
  310.         tComp = hue-180;
  311.         dstRGB->red = 0;
  312.         dstRGB->green = 0xFFFF - (tComp * tProp);
  313.         dstRGB->blue = 0xFFFF;
  314.     } else if ( hue <= 300) {                            // 241-300 red+
  315.         tComp = hue-240;
  316.         dstRGB->red = 0 + (tComp * tProp);
  317.         dstRGB->green = 0;
  318.         dstRGB->blue = 0xFFFF;
  319.     } else {                                            // 301-360 blue-
  320.         tComp = hue-300;
  321.         dstRGB->red = 0xFFFF;
  322.         dstRGB->green = 0;
  323.         dstRGB->blue = 0xFFFF - (tComp * tProp);
  324.     }
  325.  
  326.     //--------------------------------------
  327.     // This color is now 100% saturated.  Take 
  328.     // the difference betwee this color and white, 
  329.     // divide into 100 parts, add 1 for every 
  330.     // 1 part less than 100% saturation.
  331.     //  
  332.  
  333.     if ( sat != 100) {
  334.         unsigned short dR, dG, dB, invSat;
  335.  
  336.         dR = (0xFFFF - dstRGB->red)/100;
  337.         dG = (0xFFFF - dstRGB->green)/100;
  338.         dB = (0xFFFF - dstRGB->blue)/100;
  339.         invSat = 100 - sat;
  340.         dstRGB->red = dstRGB->red + (invSat*dR);
  341.         dstRGB->green = dstRGB->green + (invSat*dG);
  342.         dstRGB->blue = dstRGB->blue + (invSat*dB);
  343.     } /* else { already set} */
  344.  
  345.     //--------------------------------------
  346.     // now divide by brightness
  347.     if ( bright != 100 ) {
  348.         char b = bright;    // get rid of 68k 'long multiply'
  349.     
  350.         dstRGB->red = (dstRGB->red/100) * b;
  351.         dstRGB->green = (dstRGB->green/100) * b;
  352.         dstRGB->blue = (dstRGB->blue/100) * b;
  353.     } /* else { already set} */
  354.     
  355.     return noErr;
  356. }
  357.  
  358.  
  359. //----------------------
  360. short IRandom( short min, short max)
  361. {
  362.     short    r;
  363.     
  364.     // TO DO: Handle Negative Range
  365.     r = Random();
  366.     if ( r < 0) r *= -1;
  367.     return ((r % (max - min)) + min);
  368. }
  369.  
  370.  
  371. //**********************************************************************************
  372. //                                                      E N D   O F   L I S T I N G                                                            E N D   O F   L I S T I N G
  373.